﻿#region using

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

#endregion

namespace JupiterLibrary
{
    public class Gizmo
    {
        protected VB vertexBuffer;
        protected IB indexbuffer;
        protected int numVertices;
        protected int numPrimitives;
        public Color Color=Color.Red;

        public void Draw(Node node)
        {
            vertexBuffer.SetToDevice();

            this.indexbuffer.SetToDevice();

            BasicEffect basicEffect = Jupiter.Video.BasicEffect;

            basicEffect.World = node.World;
            basicEffect.View = Jupiter.Video.GlobalRender.Camera.View;
            basicEffect.Projection = Jupiter.Video.GlobalRender.Camera.Projection;

            basicEffect.DiffuseColor = Color.ToVector3();
            basicEffect.LightingEnabled = false;

            basicEffect.VertexColorEnabled = vertexBuffer.HasColor;

            basicEffect.Texture = null;

            basicEffect.TextureEnabled = (basicEffect.Texture != null);

            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                Jupiter.Video.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineList, 0, 0, numVertices, 0, numPrimitives);
            }
        }
    }

    public class GizmoSphere : Gizmo
    {
        int numVerticesPerCircle = 50;
        float radius=1;

        public GizmoSphere()
        {
            float delta = (float)(2.0 * Math.PI) / numVerticesPerCircle;

            int c1_offs = 0;
            int c2_offs = numVerticesPerCircle;
            int c3_offs = numVerticesPerCircle * 2;
            vertexBuffer = Jupiter.Video.VertexBuffers.CreateAndAdd();

            vertexBuffer.Position = new Vector3[numVerticesPerCircle * 3];
            
            Vector3 Position = Vector3.Zero;

            for (int i = 0; i < numVerticesPerCircle; i++)
            {
                float radians = delta * i;
                float cos = (float)Math.Cos(radians) * radius;
                float sin = (float)Math.Sin(radians) * radius;

                vertexBuffer.Position[c1_offs + i] = new Vector3(cos + Position.X, sin + Position.Y, Position.Z);
                vertexBuffer.Position[c2_offs + i] = new Vector3(cos + Position.X, Position.Y, sin + Position.Z);
                vertexBuffer.Position[c3_offs + i] = new Vector3(Position.X, cos + Position.Y, sin + Position.Z);
            }

            // Reservamos memoria para los índices
            int numIndicesPerCircle = numVerticesPerCircle * 2;
            int numIndices = numIndicesPerCircle * 3;

            indexbuffer = Jupiter.Video.IndexBuffers.CreateAndAdd();

            indexbuffer.Indices = new uint[numIndices];

            c1_offs = 0;
            c2_offs = numVerticesPerCircle;
            c3_offs = numVerticesPerCircle * 2;

            // Definimos los índices
            for (int i = 0; i < numVerticesPerCircle; i++)
            {
                int idx1, idx2;

                idx1 = i;

                if (i < numVerticesPerCircle - 1)
                    idx2 = i + 1;
                else
                    idx2 = 0;


                indexbuffer.Indices[c1_offs * 2 + i * 2 + 0] = (uint)(idx1 + c1_offs);
                indexbuffer.Indices[c1_offs * 2 + i * 2 + 1] = (uint)(idx2 + c1_offs);

                indexbuffer.Indices[c2_offs * 2 + i * 2 + 0] = (uint)(idx1 + c2_offs);
                indexbuffer.Indices[c2_offs * 2 + i * 2 + 1] = (uint)((idx2 > 0 ? idx2 : 0) + c2_offs);

                indexbuffer.Indices[c3_offs * 2 + i * 2 + 0] = (uint)(idx1 + c3_offs);
                indexbuffer.Indices[c3_offs * 2 + i * 2 + 1] = (uint)((idx2 > 0 ? idx2 : 0) + c3_offs);
            }

            numVertices = numIndices;

            numPrimitives = numIndices / 2;
            
        }

    }

    public class GizmoCube : Gizmo
    {
        int numVerticesPerCircle = 50;
        float radius = 1;

        public GizmoCube()
        {
            vertexBuffer = Jupiter.Video.VertexBuffers.CreateAndAdd();

            numVertices = 8;

            vertexBuffer.Position = new Vector3[numVertices];

            // Asumo el cubo que está en el suelo izquierda en 0,0,0

            vertexBuffer.Position[0] = new Vector3(0, 0, 0);    // Cerca, Abajo, Izquierda
            vertexBuffer.Position[1] = new Vector3(1, 0, 0);    // Cerca, Abajo, Derecha
            vertexBuffer.Position[2] = new Vector3(1, 1, 0);    // Cerca, Arriba, Derecha
            vertexBuffer.Position[3] = new Vector3(0, 1, 0);    // Cerca, Arriba, Izquierda

            vertexBuffer.Position[4] = new Vector3(0, 0, 1);    // Lejos, Abajo, Izquierda
            vertexBuffer.Position[5] = new Vector3(1, 0, 1);    // Lejos, Abajo, Derecha
            vertexBuffer.Position[6] = new Vector3(1, 1, 1);    // Lejos, Arriba, Derecha
            vertexBuffer.Position[7] = new Vector3(0, 1, 1);    // Lejos, Arriba, Izquierda

            for (int j = 0; j < 8; j++)
            {
                vertexBuffer.Position[j] += new Vector3(-0.5f, -0.5f, -0.5f);
            }

            // Reservamos memoria para los índices
            int numIndices = numVertices * 3;

            numIndices = 8*3;

            indexbuffer = Jupiter.Video.IndexBuffers.CreateAndAdd();

            indexbuffer.Indices = new uint[numIndices];

            int i = 0;

            // Frontal
            indexbuffer.Indices[0] = 0; indexbuffer.Indices[1] = 1;
            indexbuffer.Indices[2] = 1; indexbuffer.Indices[3] = 2;
            indexbuffer.Indices[4] = 2; indexbuffer.Indices[5] = 3;
            indexbuffer.Indices[6] = 3; indexbuffer.Indices[7] = 0;

            // Trasero

            i = 8;

            indexbuffer.Indices[i + 0] = 4; indexbuffer.Indices[i + 1] = 5;
            indexbuffer.Indices[i + 2] = 5; indexbuffer.Indices[i + 3] = 6;
            indexbuffer.Indices[i + 4] = 6; indexbuffer.Indices[i + 5] = 7;
            indexbuffer.Indices[i + 6] = 7; indexbuffer.Indices[i + 7] = 4;

            // Izquierdo y derecho 

            i += 8;

            indexbuffer.Indices[i + 0] = 0; indexbuffer.Indices[i + 1] = 4;
            indexbuffer.Indices[i + 2] = 3; indexbuffer.Indices[i + 3] = 7;

            indexbuffer.Indices[i + 4] = 1; indexbuffer.Indices[i + 5] = 5;
            indexbuffer.Indices[i + 6] = 2; indexbuffer.Indices[i + 7] = 6;

            numPrimitives = numIndices / 2;

        }

    }
}
